package com.petdog.common.service;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 登录尝试服务
 * 用于防止暴力破解攻击
 */
@Service
public class LoginAttemptService {
    
    private final RedisTemplate<String, String> redisTemplate;
    private static final int MAX_ATTEMPTS = 5;
    private static final int LOCK_TIME_MINUTES = 15;
    private static final String ATTEMPT_PREFIX = "login:attempt:";
    private static final String LOCK_PREFIX = "login:lock:";
    
    public LoginAttemptService(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    
    /**
     * 记录登录失败
     */
    public void loginFailed(String key) {
        String attemptKey = ATTEMPT_PREFIX + key;
        String attempts = redisTemplate.opsForValue().get(attemptKey);
        
        if (attempts == null) {
            redisTemplate.opsForValue().set(attemptKey, "1", 1, TimeUnit.HOURS);
        } else {
            int count = Integer.parseInt(attempts) + 1;
            redisTemplate.opsForValue().set(attemptKey, String.valueOf(count), 1, TimeUnit.HOURS);
            
            if (count >= MAX_ATTEMPTS) {
                lockAccount(key);
            }
        }
    }
    
    /**
     * 记录登录成功
     */
    public void loginSucceeded(String key) {
        String attemptKey = ATTEMPT_PREFIX + key;
        String lockKey = LOCK_PREFIX + key;
        
        redisTemplate.delete(attemptKey);
        redisTemplate.delete(lockKey);
    }
    
    /**
     * 检查账号是否被锁定
     */
    public boolean isLocked(String key) {
        String lockKey = LOCK_PREFIX + key;
        return redisTemplate.hasKey(lockKey);
    }
    
    /**
     * 获取锁定剩余时间（秒）
     */
    public long getLockRemainingTime(String key) {
        String lockKey = LOCK_PREFIX + key;
        return redisTemplate.getExpire(lockKey, TimeUnit.SECONDS);
    }
    
    /**
     * 获取剩余尝试次数
     */
    public int getRemainingAttempts(String key) {
        String attemptKey = ATTEMPT_PREFIX + key;
        String attempts = redisTemplate.opsForValue().get(attemptKey);
        
        if (attempts == null) {
            return MAX_ATTEMPTS;
        }
        
        int count = Integer.parseInt(attempts);
        return Math.max(0, MAX_ATTEMPTS - count);
    }
    
    /**
     * 获取当前失败次数
     */
    public int getFailedAttempts(String key) {
        String attemptKey = ATTEMPT_PREFIX + key;
        String attempts = redisTemplate.opsForValue().get(attemptKey);
        
        if (attempts == null) {
            return 0;
        }
        
        return Integer.parseInt(attempts);
    }
    
    /**
     * 锁定账号
     */
    private void lockAccount(String key) {
        String lockKey = LOCK_PREFIX + key;
        redisTemplate.opsForValue().set(lockKey, "locked", LOCK_TIME_MINUTES, TimeUnit.MINUTES);
    }
}
